﻿using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Wisdom.Core;

namespace Wisdom.Web.Mvc
{
    public class MvcBootstrapper : Bootstrapper
    {
        public MvcBootstrapper(IObjectContainer objectContainer, IBuildManager buildManager, IBootstrapperTasksRegistry bootstrapperTasks, IPerRequestTasksRegistry perRequestTasks)
            : base(objectContainer, buildManager, bootstrapperTasks, perRequestTasks)
        {
        }

        protected override void Register(IObjectContainer objectContainer)
        {
            objectContainer
                .RegisterInstance(RouteTable.Routes)
                .RegisterInstance(GlobalFilters.Filters)
                .RegisterInstance(BuildManager)
                .RegisterAsSingleton<IFilterRegistry, FilterRegistry>()
                .RegisterAsSingleton<IFilterProvider, FilterProvider>()
                .RegisterAsSingleton<IModelMetadataRegistry, ModelMetadataRegistry>();

            BuildManager.ConcreteTypes
                        .Where(type => KnownTypes.BootstrapperTaskType.IsAssignableFrom(type))
                        .Each(type => objectContainer.RegisterAsSingleton(type));

            BuildManager.ConcreteTypes
                        .Where(type => KnownTypes.PerRequestTaskType.IsAssignableFrom(type))
                        .Each(type => objectContainer.RegisterAsPerRequest(type));

            objectContainer
                .RegisterInstance<IServiceRegistrar>(objectContainer)
                .RegisterInstance<IDependencyResolver>(new DependencyResolverWrapper(objectContainer))
                .RegisterInstance<IServiceInjector>(objectContainer)
                .RegisterInstance(objectContainer)
                .RegisterInstance(BootstrapperTasks)
                .RegisterInstance(PerRequestTasks)
                .RegisterInstance(new TypeMappingRegistry<Controller, IActionInvoker>())
                .RegisterInstance(new TypeMappingRegistry<Controller, IControllerActivator>())
                .RegisterInstance(new TypeMappingRegistry<IView, IViewPageActivator>())
                .RegisterInstance(new TypeMappingRegistry<object, IModelBinder>());
        }

        protected override void SetDependencyResolver(IObjectContainer objectContainer)
        {
            DependencyResolver.SetResolver(new DependencyResolverWrapper(objectContainer));
        }
    }
}